package com.wang.jmonkey.common.utils;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.stream.Stream;

/**
 * @Description FTP文件存储工具类
 * @Author HeJiawang
 * @Date 2021/5/8 9:42
 */
public class FtpFileUtil {

    private String ip;
    private int port;
    private String user;
    private String password;

    private FtpFileUtil(String ip, int port, String user, String password) {
        this.ip = ip;
        this.port = port;
        this.user = user;
        this.password = password;
    }

    public static FtpFileUtil build(String ip, int port, String user, String password) {
        return new FtpFileUtil(ip, port, user, password);
    }

    /**
     * 上传文件到服务器
     * @param filePath 目标目录 如 /20201208/ct/test.dcm  或  20201208/ct/test.dcm
     * @param file 上传的文件
     * @return
     */
    public boolean uploadFile(String filePath, InputStream file) throws Exception {
        boolean result = false;

        FTPClient ftpClient = new FTPClient();
        if (connect(ftpClient)) {

            try {
                // 创建多级目录
                String workingPath = FilenameUtils.getFullPathNoEndSeparator(filePath);
                if (workingPath.startsWith("/")) {
                    workingPath = workingPath.substring(1);
                }
                String[] dirs = workingPath.split("/");
                for (int i = 0; i < dirs.length; i++) {
                    StringBuffer sb = new StringBuffer("/" + dirs[i]);

                    Stream.iterate(i, num -> num - 1).limit(i).forEach(num -> {
                        sb.insert(0, "/" + dirs[num - 1]);
                    });

                    String dirPath = sb.toString();
                    if (!ftpClient.changeWorkingDirectory(dirPath)) {

                        ftpClient.makeDirectory(dirPath);
                        ftpClient.changeWorkingDirectory(dirPath);
                    }
                }

                result = storeFile(ftpClient, file, FilenameUtils.getName(filePath));
            } finally {

                disconnect(ftpClient);
            }
        }

        return result;
    }

    private void disconnect(FTPClient ftpClient) throws IOException{
        if (ftpClient.isConnected()) {
            ftpClient.disconnect();
        }
    }

    private boolean connect(FTPClient ftpClient) throws Exception {
        boolean result = false;


        ftpClient.connect(this.ip, this.port);
        ftpClient.enterLocalPassiveMode();
        ftpClient.setControlEncoding("UTF-8");

        if (ftpClient.login(this.user, this.password)) {

            result = true;
        } else {
            disconnect(ftpClient);
        }

        return result;
    }

    private boolean storeFile(FTPClient ftpClient, InputStream file, String fileName) throws IOException {
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        return ftpClient.storeFile(fileName, file);
    }

    public static void main(String[] args) throws Exception {
        FtpFileUtil.build("192.168.1.102", 21, "wx-ftp", "wx-ftp")
                .uploadFile("test/a.txt", new FileInputStream(new File("F:\\temp\\a.txt")));
    }
}
